package org.breathe.dynamic.thread.pool.core.thread;

import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import org.breathe.dynamic.thread.pool.core.reject.RejectHandlerGetter;
import org.breathe.dynamic.thread.pool.core.spring.TaskWrapper;
import org.breathe.thread.pool.common.entity.NotifyItem;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 动态线程池继承了ThreadPoolExecutor，拓展了功能。
 * @author: breathe
 * @createTime: 2025-04-09
 */
public class BreatheDtpExecutor extends ThreadPoolExecutor {
    /**
     * 唯一标识
     */
    @Setter
    @Getter
    private String threadPoolName;

    /**
     * 总的拒绝次数
     */
    private final AtomicInteger rejectCount = new AtomicInteger(0);

    /**
     * 拒绝策略名字
     */
    @Getter
    @Setter
    private String rejectHandlerName;

    /**
     * 报警平台
     */
    @Setter
    @Getter
    private List<NotifyItem> notifyItems;

    /**
     * 线程池别名
     */
    private String threadPoolAliasName;

    /**
     * 存储任务的集合
     */
    private List<TaskWrapper> taskWrappers = Lists.newArrayList();

    /**
     * 是否提前创建所有的核心线程
     */
    @Setter
    @Getter
    private boolean preStartAllCoreThreads;

    /**
     *任务执行超时时间（ms）
     */
    @Setter
    @Getter
    private long runTimeout;

    /**
     * 队列等待超时时间
     */
    @Setter
    @Getter
    private long queueTimeout;
    /**
     * 执行超时次数
     */
    @Setter
    @Getter
    private final AtomicInteger runTimeoutCount = new AtomicInteger(0);

    /**
     * 队列等待超时次数
     */
    @Setter
    @Getter
    private final AtomicInteger queueTimeoutCount = new AtomicInteger(0);
    public BreatheDtpExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        this.rejectHandlerName = handler.getClass().getSimpleName();
        RejectHandlerGetter.getProxy(handler);
    }

    public void incRejectCount(int count) {
        rejectCount.addAndGet(count);
    }

    public int getRejectCount() {
        return rejectCount.get();
    }

    public String getQueueName() {
        return getQueue().getClass().getSimpleName();
    }

    public int getQueueCapacity() {
        return getQueue().size() + getQueue().remainingCapacity();
    }
}
